package com.sport.sportticketserver.service;

import com.alibaba.fastjson.JSONObject;
import com.sport.sportticketserver.common.FullConfig;
import com.sport.sportticketserver.common.SpringContextUtils;
import com.sport.sportticketserver.common.utils.QRCodeGenerator;
import com.sport.sportticketserver.common.wx.ConstantKey;
import com.sport.sportticketserver.common.wx.MD5Utils;
import com.sport.sportticketserver.common.wx.WebUtils;
import com.sport.sportticketserver.common.wx.XMLUtils;
import com.sport.sportticketserver.mapper.LogPayMapper;
import com.sport.sportticketserver.mapper.OrderMapper;
import com.sport.sportticketserver.po.LogPay;
import com.sport.sportticketserver.po.StadiumItem;
import com.sport.sportticketserver.po.UserOrder;
import com.sport.sportticketserver.vo.MerchantVO;
import com.sport.sportticketserver.vo.OrderPlaceVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Service
public class PayService {
    private final static Logger logger = LoggerFactory.getLogger(PayService.class);
    @Autowired
    LogPayMapper logPayMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    FullConfig fullConfig;
    @Autowired
    MerchantService merchantService;

    public OrderPlaceVo orderPay(HttpServletRequest request, String orderNo, BigDecimal payAmount, String openId, UserOrder order) {
        logger.error("订单id是" + orderNo + "金额" + payAmount + "openId" + openId);
        OrderPlaceVo vo = new OrderPlaceVo();
        Map<String, String> voMap = new HashMap<>();
        voMap.put("out_trade_no", orderNo);   //订单号
        voMap.put("subject", "体育支付");
        voMap.put("product_code", "QUICK_MSECURITY_PAY");
        JSONObject object = new JSONObject();

        MerchantVO merchantVO = merchantService.getTheMerchantForTheOrder(order);
        String APPID = fullConfig.getAppID();
//        String MERID = fullConfig.getWeiMerId();
//        String SIGNKEY = fullConfig.getWeiSignkey();
        String MERID = merchantVO.getWeiMerId();
        String SIGNKEY = merchantVO.getWeiSignKey();
        String spbill_create_ip = ConstantKey.getIpAddr(request);
        String tradeType = "JSAPI";
        String subject = voMap.get("subject");
        String profile = SpringContextUtils.getActiveProfile();
        String finalmoney = "10";//分
        if (profile != null && (profile.equals("pro"))) {
            finalmoney = (long) (payAmount.doubleValue() * 100) + "";//分
        }
        String out_trade_no = voMap.get("out_trade_no");
        //随机数
        String nonce_str = MD5Utils.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
        //签名数据
        StringBuilder sb = new StringBuilder();
        sb.append("appid=" + APPID);
        sb.append("&body=" + subject);
        sb.append("&mch_id=" + MERID);
        sb.append("&nonce_str=" + nonce_str);
        sb.append("&notify_url=" + fullConfig.getOrderNotifyUrl());
        sb.append("&openid=" + openId);
        sb.append("&out_trade_no=" + out_trade_no);
        sb.append("&sign_type=" + "MD5");
        sb.append("&spbill_create_ip=" + spbill_create_ip);
        sb.append("&total_fee=" + finalmoney);
        sb.append("&trade_type=" + tradeType);
        sb.append("&key=" + SIGNKEY);
        //签名MD5加密
        String sign = MD5Utils.md5Encrypt(sb.toString()).toUpperCase();
        //封装xml报文
        String xml = "<xml>" +
                "<appid>" + APPID + "</appid>" +
                "<mch_id>" + MERID + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<sign>" + sign + "</sign>" +
                "<body>" + subject + "</body>" +
                "<openid>" + openId + "</openid>" +
                "<out_trade_no>" + out_trade_no + "</out_trade_no>" +
                "<total_fee>" + finalmoney + "</total_fee>" +
                "<trade_type>" + tradeType + "</trade_type>" +
                "<notify_url>" + fullConfig.getOrderNotifyUrl() + "</notify_url>" +
                "<sign_type>MD5</sign_type>" +
                "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" +
                "</xml>";

        String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信统一下单接口
        Map map = new HashMap();
        try {
            //预下单 获取接口地址
            map = WebUtils.getMwebUrl(createOrderURL, xml);
            logger.error("订单返回数据是" + map);
            String return_code = (String) map.get("return_code");
            String return_msg = (String) map.get("return_msg");
            String result_code = (String) map.get("result_code");
            if ("SUCCESS".equals(return_code) && "OK".equals(return_msg) && "SUCCESS".equals(result_code)) {
                String non = MD5Utils.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes());
                StringBuilder againsb = new StringBuilder();
                againsb.append("appId=" + APPID);
                againsb.append("&nonceStr=" + non);
                againsb.append("&package=prepay_id=" + (String) map.get("prepay_id"));
                againsb.append("&signType=MD5");
                String s = System.currentTimeMillis() / 1000 + "";
                againsb.append("&timeStamp=" + s);
                againsb.append("&key=" + SIGNKEY);
                //签名MD5加密
                String againsign = MD5Utils.md5Encrypt(againsb.toString()).toUpperCase();
                vo.setNonceStr(non);
                vo.setPaySign(againsign);
                vo.setTimeStamp(s);
                vo.setAppId(fullConfig.getAppID());
                vo.setMini_package("prepay_id=" + (String) map.get("prepay_id"));
                vo.setOrderNo(out_trade_no);
            } else {
                String err_code_des = (String) map.get("err_code_des");
                vo.setMessage(return_msg);
                logger.error("支付出错" + JSONObject.toJSONString(map));
            }
            //查询订单是否有
            LogPay userPayLog = logPayMapper.selectVoByOrderNo(out_trade_no);
            if (userPayLog == null) {
                userPayLog = new LogPay();
                userPayLog.setOrderNo(out_trade_no);
                userPayLog.setRequestParams(sb.toString());
                userPayLog.setCreateTime(LocalDateTime.now());
                userPayLog.setLogType(0);
                logPayMapper.insertSelective(userPayLog);
            } else {
                userPayLog.setRequestParams(sb.toString());
                userPayLog.setCreateTime(LocalDateTime.now());
                logPayMapper.updateByPrimaryKeySelective(userPayLog);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.error("返回结果是" + JSONObject.toJSONString(vo));
        return vo;
    }

    public void handlerNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        BufferedReader reader = request.getReader();
        String line = "";
        Map<String, String> map = new HashMap();
        String xml = "<xml><return_code><![CDATA[FAIL]]></xml>";
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        request.getReader().close();
        logger.info("----接收到的报文---" + inputString.toString());
        if (inputString.toString().length() > 0) {
            map = XMLUtils.parseXmlToList(inputString.toString());
        } else {
            logger.info("接受微信报文为空");
        }
        logger.info("========================================");
        logger.info("----接收到的报文转化map值---" + map);
        if (map != null && "SUCCESS".equals(map.get("result_code"))) {
            //验证签名
            if (1 == 1) {
                //TODO  处理逻辑
                callBack(map);
            } else {
                logger.error("----微信支付回调签名失败---" + map);
            }
            //成功的业务。。。
            xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        } else {
            //失败的业务。。。
            logger.error("----微信支付回调失败，数据出错---" + map);
        }
        //告诉微信端已经确认支付成功
        response.getWriter().write(xml);


    }

}
